package logic;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Path;
import java.util.Properties;
import java.util.regex.Pattern;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.PasswordAuthentication;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.JFileChooser;

/**
 * Classe de Cadastro dos usuários
 * @author Guilherme
 *
 */
public class CRUDUsers {
	
	// Path do pasta do usuario 
	public static String USERPATH = new JFileChooser().getFileSystemView().getDefaultDirectory().toString();
	public static String SEPARATOR = System.getProperty("file.separator");
	public static String COOLRENT_FOLDER = "coolrent";
	public static String USERS_FOLDER = "users";
	
	/**
	 * Adiciona usuario ao sistema.
	 * @param firstName Primeiro nome do usuario.
	 * @param lastName Sobrenome do usuario.
	 * @param email Email do usuario.
	 * @param password Senha do usuario.
	 * @param sala Sala do usuario.
	 * @return true quando o usuario for adicionado ao sistema
	 * @throws Exception Caso o usuário já esteja cadastrado ou email passado seja inválido.
	 */
	public static boolean addUser(String firstName, String lastName, String email, String password, String sala) throws Exception{
		email = email.toLowerCase();
		if (validEmail(email)){
			if (userExists(email)){
				throw new Exception("Usuário já cadastrado.");
			} else { 
				File usersFolder = new File(USERPATH + SEPARATOR + COOLRENT_FOLDER + SEPARATOR + USERS_FOLDER);
				if (!usersFolder.exists()){ 
					
					usersFolder.mkdirs(); 
					}
				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(USERPATH + SEPARATOR + COOLRENT_FOLDER + SEPARATOR + USERS_FOLDER + SEPARATOR + email + ".data"));
				oos.writeObject(new Teacher(firstName, lastName, email, password, sala));
				oos.close();
				return true;
			}
		} else {
			throw new Exception("Email inválido.");
		}
	}
	
	/**
	 * Verifica se o email e valido
	 * @param email Email a ser verificado
	 * @return true se o email for valido, caso contrario false
	 */
	private static boolean validEmail(String email) {
            String re = "^[\\w-]+(\\.[\\w-]+)*@[a-zA-Z0-9]([\\w-]+\\.)+[a-zA-Z]{2,7}$";
            Pattern pattern = Pattern.compile(re);
            return pattern.matcher(email).matches();
	}

	/**
	 * Deleta o usuario do sistema
	 * @param email Email do usuario a ser deletado
	 * @return true Se o usuario for deletado
	 */
	public static boolean deleteUser(String email){
		if (userExists(email)){
			
			System.gc(); // a função file.delete() é bugada. :|
			File userFile = new File(USERPATH + SEPARATOR + COOLRENT_FOLDER + SEPARATOR + USERS_FOLDER + SEPARATOR + email + ".data");
			userFile.setWritable(true);
			System.out.println(userFile.exists() ? "existe" : "não existe");
			System.out.println((userFile.delete()) ? "deletado" : "não deletado");
			System.gc();
			return true;
		} 
		return false;
	}
	
	/**
	 * Verifies if the user already exists in the system.
	 * @param email Email of the user to be searched for.
	 * @return true if the user already has an account, false otherwise.
	 */
	private static boolean userExists(String email){
		System.out.println("UserExists >> " + email );
		File f = new File(USERPATH + SEPARATOR + COOLRENT_FOLDER + SEPARATOR + USERS_FOLDER + SEPARATOR + email + ".data");
		return f.exists();
	}
	
	/**
	 * Retorna o usuário a partir do email.
	 * @param email Email do usuário a ser retornado.
	 * @return O objeto referente ao email passado caso exista um usuário atrelado, caso contrário retorna null.
	 * @throws Exception Caso o usuário não esteja cadastrado.
	 */
	public static User getUser(String email) throws Exception{
		if (userExists(email)){
			try {
				ObjectInputStream obj = new ObjectInputStream(new FileInputStream(USERPATH + SEPARATOR + COOLRENT_FOLDER + SEPARATOR + USERS_FOLDER + SEPARATOR + email + ".data"));
				return (Teacher) obj.readObject();
			} catch (IOException | ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		throw new Exception("Usuário não cadastrado no sistema.");
	}
	
	/**
	 * Manda um email para um usuário, lembrando a senha do mesmo.
	 * @param email Email do usuário.
	 * @return true se o email foi enviado. 
	 * @throws Exception Caso o usuário não esteja cadastrado.
	 */
	
	public static boolean retrievePassword(String email) throws Exception{
		if (validEmail(email) && userExists(email)){
			final String coolrentEmail = "coolrent.noreply@gmail.com"; //TODO gmail account;
			final String coolrentPassword = "#coolrent#";
			
			// cookbook to send an email.
			Properties props = new Properties();
			props.put("mail.smtp.auth", "true");
			props.put("mail.smtp.starttls.enable", "true");
			props.put("mail.smtp.host", "smtp.gmail.com");
			props.put("mail.smtp.port", "587");
	 
	 
			Session session = Session.getInstance(props,
			  new javax.mail.Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(coolrentEmail, coolrentPassword);
            }
			  });
	 
			try {
	 
				Message message = new MimeMessage(session);
				message.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse(email));
				message.setSubject("Lembrete de Senha.");
				message.setText("Sua senha é " + getUser(email).getPassword() + ".\n []'s");
	 
				Transport.send(message);
				
				return true;
	
			} catch (MessagingException e) {
				throw new RuntimeException(e);
			}
			
		}
		throw new Exception("Email não cadastrado!");
	}
	
	public static void main(String[] args) throws Exception {
		try {
			//CRUDUsers.deleteUser("paulorugal@gmail.com");
			//CRUDUsers.addUser("paulo", "sergio", "paulorugal@gmail.com", "senha", "splab101");
			Teacher t = (Teacher) CRUDUsers.getUser("paulorugal@gmail.com");
			System.out.println(CRUDUsers.userExists("paulorugal@gmail.com"));
			System.out.println(t);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
